package com.yowasa.xiuxian.util;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;

public class RandomUtil {
    private final static Random random = new Random();


    /**
     * 波动
     * @param value 原值
     * @param rate 波动幅度 0-100
     * @return
     */
    public static int waveInt(int value, int rate) {
        int i = randomInt(100 - rate, 100 + rate);
        return value * i / 100;
    }

    /**
     * 生成随机属性 4d6取3*5波动5
     * @return
     */
    public static int genRandomAttr() {
        List<Integer> rolls = Lists.newArrayList();
        for (int i = 0; i < 4; i++) {
            rolls.add(random.nextInt(6) + 1);
        }
        rolls.sort(Integer::compareTo);
        int sum = 0;
        for (int i = 1; i < 4; i++) {
            sum += rolls.get(i);
        }
        return sum * 5 + random.nextInt(11) - 5;
    }


    public static int randomInt(int begin,int end) {
        return random.nextInt(end - begin + 1) + begin;
    }
    public static int randomInt(int end) {
        return randomInt(0, end);
    }

    /**
     * 红包拆分
     *
     * @param amount 额度
     * @param min    每份最小
     * @param num    份数
     */
    public static List<BigDecimal> redPackSplit(BigDecimal amount, BigDecimal min, BigDecimal num) {
        final int[] rand = new int[num.intValue()];
        BigDecimal sum1 = BigDecimal.ZERO;
        BigDecimal redpeck;
        int sum = 0;
        for (int i = 0; i < num.intValue(); i++) {
            rand[i] = random.nextInt(100);
            sum += rand[i];
        }
        List<BigDecimal> result = Lists.newArrayList();
        final BigDecimal bigDecimal = new BigDecimal(sum);
        BigDecimal remain = amount.subtract(min.multiply(num));
        for (int i = 0; i < rand.length; i++) {
            if (i == num.intValue() - 1) {
                redpeck = remain;
            } else {
                redpeck = remain.multiply(new BigDecimal(rand[i])).divide(bigDecimal, 2, RoundingMode.FLOOR);
            }
            if (remain.compareTo(redpeck) > 0) {
                remain = remain.subtract(redpeck);
            } else {
                remain = BigDecimal.ZERO;
            }
            sum1 = sum1.add(min.add(redpeck));
            result.add(min.add(redpeck));
        }
        return result;
    }

    /**
     * int拆分
     *
     * @param amount 数值
     * @param min    每份最小
     * @param num    份数
     */
    public static List<Integer> intSplit(int amount, int min, int num) {
        List<BigDecimal> splits = redPackSplit(new BigDecimal(amount).divide(BigDecimal.valueOf(100L)), new BigDecimal(min).divide(BigDecimal.valueOf(100L)), new BigDecimal(num));
        return splits.stream().map(e -> e.multiply(BigDecimal.valueOf(100L)).intValue()).collect(Collectors.toList());
    }

    public static <T> T choice(List<T> list) {
        return list.get(random.nextInt(list.size()));
    }

    /**
     * 获取map的value最大的n个key
     * @param map
     * @param n
     * @param <K>
     * @param <V>
     * @return
     */
    public static  <K,V extends Comparable> Set<K> getTopKey(Map<K,V> map, int n) {
        Set<K> result = Sets.newHashSet();
        if (map.size() <= n) {
            return map.keySet();
        }
        List<K> collect = map.entrySet().stream().sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue())).map(e -> e.getKey()).collect(Collectors.toList());
        List<K> tops = collect.subList(0, n);
        result.addAll(tops);
        return result;
    }
}
